package com.spica.platform.user.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.spica.platform.base.model.*;
import com.spica.platform.common.constant.CommonConstant;
import com.spica.platform.common.constant.UserType;
import com.spica.platform.common.utils.EntityUtil;
import com.spica.platform.db.service.impl.ServiceImpl;
import com.spica.platform.user.exception.SysUserException;
import com.spica.platform.user.exception.SysUserRtnCodEnum;
import com.spica.platform.user.mapper.SysUserMapper;
import com.spica.platform.user.model.SysUserExcel;
import com.spica.platform.user.model.SysUserRole;
import com.spica.platform.user.model.request.SysUserQueryParam;
import com.spica.platform.user.service.ISysRoleMenuService;
import com.spica.platform.user.service.ISysUserRoleService;
import com.spica.platform.user.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description 描述 获取用户服务类
 * 类命名规则findXXX, updateXXX, removeXXX, saveXXX
 * @Author andy
 * @Date 2025/4/10
 */
@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

	@Autowired
	private PasswordEncoder passwordEncoder;

	@Resource
	private ISysUserRoleService sysUserRoleService;

	@Resource
	private ISysRoleMenuService roleMenuService;

	/**
	 * 根据用户名查询用户
	 */
	@Override
	public SysUser findSysUserByUsername(String username) {
		List<SysUser> users = baseMapper.selectList(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
		return getUser(users);
	}
	
	@Override
	public LoginAppUser findLoginAppUserBySysUser(SysUser sysUser) {
		if (sysUser != null) {
			LoginAppUser loginAppUser = new LoginAppUser();
			//其他字段从sysUser中copy
			BeanUtils.copyProperties(sysUser, loginAppUser);
			//查出角色信息
			List<SysRole> sysRoles = sysUserRoleService.findRolesByUserId(sysUser.getId());
			// 设置角色
			loginAppUser.setRoles(sysRoles);
			//获取权限信息
			if (!CollectionUtils.isEmpty(sysRoles)) {
				Set<Long> roleIds = sysRoles.stream().map(BaseEntity::getId).collect(Collectors.toSet());
				List<SysMenu> menus = roleMenuService.findSysMenusByRoleIds(roleIds, CommonConstant.PERMISSION);
				if (!CollectionUtils.isEmpty(menus)) {
					Set<String> permissions = menus.stream().map(p -> p.getPath()).collect(Collectors.toSet());
					// 设置权限集合
					loginAppUser.setPermissions(permissions);
				}
			}
			return loginAppUser;
		}
		return null;
	}

	/**
	 * 根据手机号查询用户
	 */
	@Override
	public SysUser findSysUserByMobile(String mobile) {
		List<SysUser> users = baseMapper.selectList(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getMobile, mobile));
		return getUser(users);
	}

	@Override
	public SysUser findSysUserByOpenId(String openId) {
		List<SysUser> users = baseMapper.selectList(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getOpenId, openId));
		return getUser(users);
	}

	@Override
	public PageResult<SysUser> findSysUsersByParam(Page<SysUser> page, SysUserQueryParam sysUserQueryParam) {
		List<SysUser> list = baseMapper.selectListByParam(page, sysUserQueryParam);

		if (!CollectionUtils.isEmpty(list)) {
			List<Long> userIds = EntityUtil.toList(list, SysUser::getId) ;
			List<SysRole> sysRoles = sysUserRoleService.findRolesByUserIds(userIds);
			list.forEach(u -> u.setRoles(sysRoles.stream().filter(r -> !ObjectUtils.notEqual(u.getId(), r.getUserId()))
					.collect(Collectors.toList())));
		}
		return PageResult.<SysUser>builder().data(list).rtnCod(0).count(page.getTotal()).build();
	}

	@Override
	public boolean updateAccountStatus(Long id, Integer accountStatus) {
		SysUser appUser = baseMapper.selectById(id);
		appUser.setAccountStatus(accountStatus);
		log.info("修改用户：{}", appUser);
		return baseMapper.updateById(appUser) > 0;
	}

	@Transactional
	@Override
	public boolean updatePassword(Long id, String oldPassword, String newPassword) {

		boolean flag = false;
		SysUser sysUser = baseMapper.selectById(id);
		if (StrUtil.isNotBlank(oldPassword)) {
			if (!passwordEncoder.matches(oldPassword, sysUser.getPassword())) {
				throw new SysUserException(SysUserRtnCodEnum.SYS_USER_00003);
			}
		}
		if (StrUtil.isBlank(newPassword)) {
			newPassword = CommonConstant.DEF_USER_PASSWORD;
		}
		SysUser user = new SysUser();
		user.setId(id);
		user.setPassword(passwordEncoder.encode(newPassword));
		return baseMapper.updateById(user) > 0;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public boolean delUser(Long id) {
		sysUserRoleService.deleteUserRole(id, null);
		return baseMapper.deleteById(id) > 0;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public boolean saveOrUpdateUser(SysUser sysUser) {

		boolean flag = false;

		if (sysUser.getId() == null) {

			long count = this.count(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, sysUser.getUsername()));
			if(count > 0) {
				throw new SysUserException(SysUserRtnCodEnum.SYS_USER_0000B);
			}

			if (null == sysUser.getType()) {
				sysUser.setType(UserType.BACKEND.getCode());
			}
			sysUser.setPassword(passwordEncoder.encode(CommonConstant.DEF_USER_PASSWORD));
			sysUser.setAccountStatus(1);
		}
		this.saveOrUpdate(sysUser);
		if (StrUtil.isNotEmpty(sysUser.getRoleId())) {
			// 更新角色
			sysUserRoleService.deleteUserRole(sysUser.getId(), null);
			List roleIds = Convert.toList(sysUser.getRoleId());
			if (!CollectionUtils.isEmpty(roleIds)) {
				List<SysUserRole> roleUsers = new ArrayList<>(roleIds.size());
				roleIds.forEach(roleId -> roleUsers.add(SysUserRole.builder().userId(sysUser.getId())
						.roleId(Long.parseLong(roleId.toString())).build()));
				flag = sysUserRoleService.saveBatch(roleUsers);
			}
		}
		return flag;
	}

	@Override
	public List<SysUserExcel> findAllUsers(SysUserQueryParam sysUserQueryParam) {
		List<SysUserExcel> sysUserExcels = new ArrayList<>();
		List<SysUser> list = baseMapper.selectListByParam(new Page<>(1, -1), sysUserQueryParam);

		for (SysUser sysUser : list) {
			SysUserExcel sysUserExcel = new SysUserExcel();
			BeanUtils.copyProperties(sysUser, sysUserExcel);
			sysUserExcels.add(sysUserExcel);
		}
		return sysUserExcels;
	}

	private SysUser getUser(List<SysUser> users) {
		SysUser user = null;
		if (users != null && !users.isEmpty()) {
			user = users.get(0);
		}
		return user;
	}
}